﻿using System;
using System.ServiceModel.Description;
using CRMCustom.Parser;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Metadata;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk;
using System.Collections.Generic;

namespace CRMCustom.WebService
{
    /// <summary>
    /// This class provide access to CRM via a web service connection
    /// </summary>
    public static class WebServiceConnector
    {
        public static OrganizationServiceProxy CreateConnection(string serverIPAddress
            , string portNumber
            , string organizationName
            , string domain
            , string username
            , string password)
        {
            ClientCredentials clientCredentials = new ClientCredentials();
            clientCredentials.Windows.ClientCredential.Domain = domain;
            clientCredentials.Windows.ClientCredential.UserName = username;
            clientCredentials.Windows.ClientCredential.Password = password;

            OrganizationServiceProxy proxy = new OrganizationServiceProxy(
                new Uri(string.Format("http://{0}:{1}/{2}", serverIPAddress, portNumber, organizationName))
                , null
                , clientCredentials
                , null);

            return proxy;
        }
      
        public static void CreateEntity(ExtendedEntityMetadata metadata, OrganizationServiceProxy proxy, string solutionName)
        {
            if (metadata.IncludeInTransaction)
            {
                CreateEntityRequest request = new CreateEntityRequest();

                request.Entity = metadata.Metadata;
                request.HasActivities = metadata.HasActivities;
                request.HasNotes = metadata.HasNotes;
                request.PrimaryAttribute = metadata.PrimaryAttribute;

                request.SolutionUniqueName = solutionName;

                CreateEntityResponse response = (CreateEntityResponse)proxy.Execute(request);

                //TODO: parse CreateEntityResponse and update error message on metadata

            }
        }

        public static void CreateAttribute(ExtendedAttributeMetadata metadata, OrganizationServiceProxy proxy, string solutionName)
        {
            if (metadata.IncludeInTransaction)
            {
                CreateAttributeRequest request = new CreateAttributeRequest();

                request.SolutionUniqueName = solutionName;

                request.EntityName = metadata.OwnerEntity.ToLower();
                request.Attribute = metadata.Attribute;

                if (metadata.Attribute is LookupAttributeMetadata)
                {
                    LookupAttributeMetadata lookupMetadata = metadata.Attribute as LookupAttributeMetadata;

                    OneToManyRelationshipMetadata relationship
                        = new OneToManyRelationshipMetadata
                        {
                            ReferencedEntity = lookupMetadata.Targets[1],
                            ReferencingEntity = lookupMetadata.Targets[0],
                            SchemaName = string.Format(@"new_{0}_{1}", lookupMetadata.Targets[1], lookupMetadata.Targets[0])
                        };

                    CreateOneToManyRequest createRelationshipRequest = new CreateOneToManyRequest { Lookup = lookupMetadata, OneToManyRelationship = relationship };

                    //TODO: parse CreateAttributeResponse and update error message on metadata
                    proxy.Execute(createRelationshipRequest);
                    return;
                }
                else if (metadata.Attribute is PicklistAttributeMetadata)
                {
                    PicklistAttributeMetadata pickListMetadata = metadata.Attribute as PicklistAttributeMetadata;

                    if (pickListMetadata.OptionSet.IsGlobal.HasValue
                        && pickListMetadata.OptionSet.IsGlobal.Value) //Create new OptionSet
                        proxy.Execute(new CreateOptionSetRequest { SolutionUniqueName=solutionName, OptionSet = pickListMetadata.OptionSet });


                    //Reset options: This attribute should be referring to option set by name, therefore Options have to be emptied
                    string optionSetName = pickListMetadata.OptionSet.Name;
                    pickListMetadata.OptionSet = new OptionSetMetadata();
                    pickListMetadata.OptionSet.Name = optionSetName;

                    pickListMetadata.OptionSet.IsGlobal = true;
                    pickListMetadata.OptionSet.OptionSetType = OptionSetType.Picklist;

                }
                //TODO: parse CreateAttributeResponse and update error message on metadata
                proxy.Execute(request);
            }
        }
    }
}
